import React from 'react';
import { useDropzone } from 'react-dropzone';

import { ReactComponent as DeleteImg } from '@/assets/images/auth/DeleteImg.svg';
import { ReactComponent as Loader } from '@/assets/images/auth/Loader.svg';
import { ReactComponent as Paperclip } from '@/assets/images/auth/Paperclip.svg';
import { ReactComponent as Camera } from '@/assets/images/profile/Camera.svg';
import { FileWithPreview } from '@/shared/interfaces';
import { Snackbar } from '@/shared/ui';
import classNames from 'classnames';
import { useSnackbar } from 'notistack';
import { useWindowSize } from 'usehooks-ts';

import s from './Dropzone.module.scss';

export const Dropzone = ({
  isLoading,
  fromModal,
  onChange,
  handleDrop,
}: {
  isLoading: boolean;
  fromModal?: boolean;
  onChange?: (files?: File[]) => void;
  handleDrop?: (files?: FileWithPreview[]) => void;
}) => {
  const [files, setFiles] = React.useState<FileWithPreview[]>([]);
  const [error, setError] = React.useState<boolean>(false);
  const { width } = useWindowSize();

  React.useEffect(() => {
    if (error) {
      setTimeout(() => {
        setError(false);
      }, 1500);
    }
  }, [error]);

  const { enqueueSnackbar } = useSnackbar();

  const baseStyle: React.CSSProperties = {
    display: 'flex',
    cursor: 'pointer',
  };

  const mobileBaseStyle: React.CSSProperties = {
    display: 'flex',
  };

  const activeStyle: React.CSSProperties = {
    border: '1px dashed var(--simple-blue-day, #337CEC)',
    background: 'var(--pastel-blue, #EBF1FC)',
  };

  React.useEffect(() => {
    if (onChange && files.length >= 1) {
      onChange(files);
    }
  }, [files.length]);

  const onDrop = React.useCallback(
    (acceptedFiles: File[]) => {
      const filesWithPreview: FileWithPreview[] = acceptedFiles
        .filter((file) => {
          const isDuplicate = files.some((existingFile) => existingFile.name === file.name);
          return !isDuplicate;
        })
        .map((file) => {
          const fileWithPreview = file as FileWithPreview;
          fileWithPreview.preview = URL.createObjectURL(file);
          return fileWithPreview;
        });

      setFiles((prev) => [...prev, ...filesWithPreview]);
      !fromModal && handleDrop?.(filesWithPreview);
    },
    [files, fromModal],
  );

  const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({
    onDrop,
    onDropRejected(fileRejections) {
      setError(true);
      enqueueSnackbar(fileRejections[0].errors[0].code === 'file-too-large' ? 'Размер превышен' : 'Неверный формат', {
        variant: 'error',
        content: (key, message) => <Snackbar id={key} message={message} size="md" variant="error" />,
      });
    },
    accept: fromModal ? 'image/jpeg, image/png' : 'image/*, video/mp4',
    multiple: true,
    maxFiles: fromModal ? 1 : Infinity,
    maxSize: 10 * 1024 * 1024,
  });

  const style = React.useMemo(() => {
    const baseStyles = width > 768 ? baseStyle : mobileBaseStyle;

    return {
      ...baseStyles,
      ...(isDragActive ? activeStyle : {}),
    };
  }, [isDragActive, isDragReject, isDragAccept, width]);

  const onDelete = (file: FileWithPreview) => {
    const newFiles = [...files];
    newFiles.splice(newFiles.indexOf(file), 1);
    setFiles(newFiles);
  };

  const thumbs = files.map((file) => (
    <div key={file.lastModified} style={{ position: 'relative' }}>
      <span className={s.delete} onClick={() => onDelete(file)}>
        <DeleteImg />
      </span>
      {file.type !== 'video/mp4' ? (
        <img alt={file.name} className={s.img} key={file.name} src={file.preview} />
      ) : (
        <video className={s.img} height={104} poster={file.preview} src={file.preview} width={104} />
      )}
    </div>
  ));

  if (isLoading && !fromModal) {
    return (
      <div className={classNames(s.loading, { [s.fromModal]: fromModal })}>
        <div className={s.loader}>
          <Loader />{' '}
        </div>
      </div>
    );
  }
  if (isLoading && fromModal) {
    return (
      <div className={classNames(s.loadingModal, { [s.fromModal]: fromModal })}>
        <div className={s.loader}>
          <Loader />{' '}
        </div>
      </div>
    );
  }

  if (fromModal && width < 1024) {
    return (
      <div {...getRootProps({ style })} className={classNames(s.dropdownFromModal)}>
        <input {...getInputProps()} />
        <Camera /> Загрузить фото
      </div>
    );
  }

  // const handleClear = () => {
  //   dispatch(clearFeedbackFiles());
  //   setFiles([]);
  // };

  return (
    <>
      <div
        {...getRootProps({ style })}
        className={classNames(s.dropdown, { [s.fromModal]: fromModal }, { [s.error]: error })}
      >
        <input {...getInputProps()} />
        {width > 768 ? (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>
            <Paperclip />
            <p className={s.load}>
              Загрузите или перетащите {!fromModal ? 'файл' : 'фото'}{' '}
              {!fromModal && <span className={s.mb}>(до 10 мб)</span>}
            </p>
          </div>
        ) : (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <p className={s.load}>Прикрепить файл {!fromModal && <span className={s.mb}>(до 10 мб)</span>}</p>
          </div>
        )}
      </div>
      {!fromModal && files && files.length > 0 && <div className={classNames(s.files, s.show)}>{thumbs}</div>}
    </>
  );
};
